<?php

namespace App\Helpers;

class MoneyHelper
{
    const PRECISION  = 2;                    //小数点后2位
    const MODE       = PHP_ROUND_HALF_EVEN;  //舍入规则，缺省为四舍六入五凑偶
    const SEP_SYMBOL = ',';                  //千分位符号为半角逗号
    const DEP_SYMBOL = '.';                  //小数点符号
    const EPS        = 0.001;                //精度误差

    /**
     * 将人民币的元，转换成分
     * @param float $yuan
     * @return float
     */
    public static function y2f($yuan)
    {
        return self::int_fen($yuan * 100);
    }

    /**
     *      将浮点数的金额（单位:分）转为整数，避免舍入误差
     *      int_fen(19.99999)   => 20
     *      int_fen(0)          => 0
     *      int_fen(-19.99999)  => -20
     */
    public static function int_fen($f)
    {
        if (abs($f) < self::EPS) {
            return 0;
        } elseif ($f > 0) {
            return intval($f + self::EPS);
        } else { /* if ($f < 0) */
            return intval($f - self::EPS);
        }
    }

    /**
     * @param $amount
     * @return int
     */
    public static function halfEvenRound($amount)
    {
        return self::int_fen(round($amount, 0, self::MODE));
    }

    /**
     * 将分转换成元
     *
     * 如果需要格式化，则默认是有千分位的，符号缺省为半角逗号，返回类型变为字符串
     * 如果不需要格式化，返回是float类型，小数点后的0会被省略掉
     *
     * 缺省精确度为2位小数
     *
     * @param float $fen 要转换的金额，以分为单位
     * @param boolean $format 是否要格式化，缺省是false
     * @param boolean $k_separator 是否要加千分位，缺省是false
     * @return float|string 如果format参数为true，返回字符串，否则返回float
     */
    public static function f2y($fen, $format = true, $k_separator = false)
    {
        $yuan = round($fen / 100, self::PRECISION, self::MODE);
        if ($format) {
            $sep  = $k_separator ? self::SEP_SYMBOL : '';
            $yuan = number_format($yuan, self::PRECISION, self::DEP_SYMBOL, $sep);
        }

        return (float)$yuan;
    }

    /**
     * 将分转换为万
     * @param float $fen 要转换的金额，以分为单位
     * @param boolean $format 是否要格式化，缺省是true
     * @param boolean $k_separator 是否要加千分位，缺省是true
     * @return float|string
     */
    public static function f2w($fen, $format = true, $k_separator = true)
    {
        $yuan = self::f2y($fen, false);
        $bai  = self::f2y($yuan, false);

        return self::f2y($bai, $format, $k_separator);
    }

    /**
     * 将元为单位的数字转化成 中文结尾
     * @param $amount
     * @return string
     */
    public static function changeAmount($amount)
    {
        if (intval($amount) == 0) {
            return '无限额';
        }
        $num = round(intval($amount) / 1000);
        if ($num >= 10) {
            return round(intval($num) / 10) . '万';
        } else {
            return $num . '千';
        }
    }

    /**
     * 将分转化成格式化的元,并以元结尾,比如5,000,000元
     * formatY
     * @param float $fen 要转化的金额,以分为单位
     *
     * @return string
     */
    public static function formatY($fen)
    {
        return self::format($fen) . '元';
    }

    /**
     * 将金额格式化为标准格式
     * @param float $amountInFen 单位为分的金额
     * @return string 格式化后的样子，1,000.00
     */
    public static function format($amountInFen)
    {
        $yuan = self::f2y($amountInFen);

        return number_format($yuan, self::PRECISION);
    }
    public static function formatAmount($amount, $decimal = 2)
    {
        return (float)sprintf("%.{$decimal}f", $amount);
    }
}
